﻿namespace CKFinder.Connector.CommandHandlers
{
    using CKFinder;
    using CKFinder.Connector;
    using CKFinder.Settings;
    using System;
    using System.IO;
    using System.Security;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Web;

    internal class FileUploadCommandHandler : CommandHandlerBase
    {
        private bool CheckNonHtmlFile(HttpPostedFile file)
        {
            byte[] buffer = new byte[0x400];
            file.InputStream.Read(buffer, 0, 0x400);
            string input = Encoding.ASCII.GetString(buffer);
            if (Regex.IsMatch(input, @"<!DOCTYPE\W*X?HTML", RegexOptions.Singleline | RegexOptions.IgnoreCase))
            {
                return false;
            }
            if (Regex.IsMatch(input, "<(?:body|head|html|img|pre|script|table|title)", RegexOptions.Singleline | RegexOptions.IgnoreCase))
            {
                return false;
            }
            if (Regex.IsMatch(input, "type\\s*=\\s*[\\'\"]?\\s*(?:\\w*/)?(?:ecma|java)", RegexOptions.Singleline | RegexOptions.IgnoreCase))
            {
                return false;
            }
            if (Regex.IsMatch(input, "(?:href|src|data)\\s*=\\s*[\\'\"]?\\s*(?:ecma|java)script:", RegexOptions.Singleline | RegexOptions.IgnoreCase))
            {
                return false;
            }
            if (Regex.IsMatch(input, "url\\s*\\(\\s*[\\'\"]?\\s*(?:ecma|java)script:", RegexOptions.Singleline | RegexOptions.IgnoreCase))
            {
                return false;
            }
            return true;
        }

        protected virtual string GetJavaScriptCode(int errorNumber, string fileName, string fileUrl)
        {
            HttpRequest request = HttpContext.Current.Request;
            string str = "";
            if (errorNumber > 0)
            {
                str = Lang.getErrorMessage(errorNumber).Replace("%1", fileName);
                if ((errorNumber != 0xc9) && (errorNumber != 0xcf))
                {
                    fileName = "";
                }
            }
            return ("window.parent.OnUploadCompleted('" + fileName.Replace("'", @"\'") + "','" + str.Replace("'", @"\'") + "') ;");
        }

        public override void SendResponse(HttpResponse response)
        {
            int errorNumber = 0;
            string fileName = "";
            string input = "";
            try
            {
                base.CheckConnector();
                base.CheckRequest();
                if (!base.CurrentFolder.CheckAcl(AccessControlRules.FileUpload))
                {
                    ConnectorException.Throw(0x67);
                }
                HttpPostedFile file = HttpContext.Current.Request.Files[HttpContext.Current.Request.Files.AllKeys[0]];
                if (file != null)
                {
                    input = Path.GetFileName(file.FileName);
                    fileName = Regex.Replace(input, @"[\:\*\?\|\/]", "_", RegexOptions.None);
                    if (fileName != input)
                    {
                        errorNumber = 0xcf;
                    }
                    if (CKFinder.Connector.Connector.CheckFileName(fileName) && !Config.Current.CheckIsHiddenFile(fileName))
                    {
                        string str6;
                        if (Config.Current.ForceSingleExtension)
                        {
                            fileName = Regex.Replace(fileName, @"\.(?![^.]*$)", "_", RegexOptions.None);
                        }
                        if ((!Config.Current.CheckSizeAfterScaling && (base.CurrentFolder.ResourceTypeInfo.MaxSize > 0)) && (file.ContentLength > base.CurrentFolder.ResourceTypeInfo.MaxSize))
                        {
                            ConnectorException.Throw(0xcb);
                        }
                        string extension = Path.GetExtension(file.FileName).TrimStart(new char[] { '.' });
                        if (!base.CurrentFolder.ResourceTypeInfo.CheckExtension(extension))
                        {
                            ConnectorException.Throw(0x69);
                        }
                        if (Config.Current.CheckIsNonHtmlExtension(extension) && !this.CheckNonHtmlFile(file))
                        {
                            ConnectorException.Throw(0xce);
                        }
                        string serverPath = base.CurrentFolder.ServerPath;
                        string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName);
                        int num2 = 0;
                        while (true)
                        {
                            str6 = Path.Combine(serverPath, fileName);
                            if (!File.Exists(str6))
                            {
                                break;
                            }
                            num2++;
                            fileName = string.Concat(new object[] { fileNameWithoutExtension, "(", num2, ")", Path.GetExtension(file.FileName) });
                            errorNumber = 0xc9;
                        }
                        file.SaveAs(str6);
                        if ((Config.Current.SecureImageUploads && ImageTools.IsImageExtension(extension)) && !ImageTools.ValidateImage(str6))
                        {
                            File.Delete(str6);
                            ConnectorException.Throw(0xcc);
                        }
                        Images images = Config.Current.Images;
                        if ((images.MaxHeight > 0) && (images.MaxWidth > 0))
                        {
                            ImageTools.ResizeImage(str6, str6, images.MaxWidth, images.MaxHeight, true, images.Quality);
                            if ((Config.Current.CheckSizeAfterScaling && (base.CurrentFolder.ResourceTypeInfo.MaxSize > 0)) && (new FileInfo(str6).Length > base.CurrentFolder.ResourceTypeInfo.MaxSize))
                            {
                                File.Delete(str6);
                                ConnectorException.Throw(0xcb);
                            }
                        }
                    }
                    else
                    {
                        ConnectorException.Throw(0x66);
                    }
                }
                else
                {
                    ConnectorException.Throw(0xcc);
                }
            }
            catch (ConnectorException exception)
            {
                errorNumber = exception.Number;
            }
            catch (SecurityException)
            {
                errorNumber = 0x68;
            }
            catch (UnauthorizedAccessException)
            {
                errorNumber = 0x68;
            }
            catch
            {
                errorNumber = 110;
            }
            response.Clear();
            response.Write("<script type=\"text/javascript\">");
            response.Write(this.GetJavaScriptCode(errorNumber, fileName, base.CurrentFolder.Url + fileName));
            response.Write("</script>");
            response.End();
        }
    }
}

